package event

import (
	"fmt"
	"strings"
	"time"

	"go.uber.org/zap"
)

// Parse2025F183Packet 解析2025F183-37协议报文
func Parse2025F183Packet(data []byte) (*Event2025F183, error) {
	if len(data) < 16 {
		return nil, fmt.Errorf("数据长度不足")
	}

	// 提取设备地址（位置2-8）
	var deviceAddr string
	for i := 8; i >= 2; i-- {
		deviceAddr += fmt.Sprintf("%02X", data[i])
	}

	event := &Event2025F183{
		DeviceAddr: deviceAddr,
		EventData:  make(map[string]interface{}),
		EventTime:  time.Now(),
	}

	// 提取表地址（与设备地址相同）
	event.TableNumber = deviceAddr

	// 检查是否是主动上报数据(0x97)
	if len(data) < 11 || data[10] != 0x97 {
		return nil, fmt.Errorf("非主动上报数据")
	}

	// 获取数据包类型
	var dataPackType byte
	if len(data) >= 17 {
		dataPackType = data[16]
	}
	event.EventData["data_pack_type"] = dataPackType

	// 根据数据包类型确定事件类型
	switch dataPackType {
	case 0x01:
		event.EventType = "prepay_report" // 预付费表普通上报
	case 0x02:
		event.EventType = "prepay_step_report" // 预付费阶梯表上报
	case 0x03:
		event.EventType = "postpay_report" // 后付费表上报
	case 0x13:
		event.EventType = "alarm_report" // 告警上报
	case 0x14:
		event.EventType = "valve_status" // 阀门状态
	case 0x15:
		event.EventType = "battery_low" // 电池电量低
	default:
		event.EventType = "general_report" // 普通上报
	}

	// 根据不同的数据包类型解析数据
	switch dataPackType {
	case 0x01, 0x02: // 预付费表上报
		parseWaterMeterData(data, event)
	case 0x03: // 后付费表上报
		parseWaterMeterData(data, event)
	}

	return event, nil
}

// parseWaterMeterData 解析水表数据（使用water_regex.py方案为主，main.py方案验证）
func parseWaterMeterData(data []byte, event *Event2025F183) {
	if len(data) < 65 {
		zap.S().Warnf("水表数据长度不足: %d < 65", len(data))
		return
	}

	// 数据内容从位置17开始（去掉帧头和数据包类型）
	dataContent := data[17:]

	// 方案1：使用water_regex.py的解析方案（主方案）
	parsedDataRegex, errRegex := parseWaterMeterDataRegex(dataContent)

	// 方案2：使用main.py的原方案（验证方案）
	parsedDataMain, errMain := parseWaterMeterDataMain(dataContent)

	// 优先使用water_regex方案
	var primaryData map[string]interface{}
	var primaryErr error

	if errRegex == nil {
		primaryData = parsedDataRegex
		primaryErr = errRegex

		// 如果两个方案都成功，进行数据对比验证
		if errMain == nil {
			compareWaterMeterDifferences(parsedDataRegex, parsedDataMain, event.DeviceAddr)
		}
	} else if errMain == nil {
		// water_regex方案失败，使用main.py方案兜底
		zap.S().Warnf("设备[%s] water_regex方案解析失败: %v, 使用main.py方案兜底", event.DeviceAddr, errRegex)
		primaryData = parsedDataMain
		primaryErr = errMain
	} else {
		// 两个方案都失败
		zap.S().Warnf("设备[%s] 两种解析方案都失败, water_regex: %v, main.py: %v", event.DeviceAddr, errRegex, errMain)
		return
	}

	// 使用主方案的数据
	if primaryErr == nil && primaryData != nil {
		for key, value := range primaryData {
			event.EventData[key] = value
		}

		// 标记使用的解析方案
		event.EventData["parse_method"] = "water_regex"
	}
}

// parseWaterMeterDataRegex 基于water_regex.py方案解析（主方案）
func parseWaterMeterDataRegex(data []byte) (map[string]interface{}, error) {
	if len(data) < 61 {
		return nil, fmt.Errorf("数据长度不足")
	}

	result := make(map[string]interface{})

	// 数据域偏移量定义（参考 water_regex.py POSTPAID_FIELDS）

	// 解析状态字（偏移量41，2字节，大端序）
	const STATUS_OFFSET = 41
	if len(data) >= STATUS_OFFSET+2 {
		status := (uint16(data[STATUS_OFFSET]) << 8) | uint16(data[STATUS_OFFSET+1])
		result["status"] = status

		// 解析状态位
		result["valve_closed"] = (status & 0x0001) != 0
		result["battery_low"] = (status & 0x0002) != 0
		result["meter_error"] = (status & 0x0004) != 0
		result["reverse_flow"] = (status & 0x0008) != 0
		result["no_flow"] = (status & 0x0010) != 0
		result["leakage"] = (status & 0x0020) != 0
	}

	// 解析累计用量（偏移量43，4字节，大端序，单位升）
	const TOTAL_USAGE_OFFSET = 43
	if len(data) >= TOTAL_USAGE_OFFSET+4 {
		totalValue := uint32(data[TOTAL_USAGE_OFFSET])<<24 |
			uint32(data[TOTAL_USAGE_OFFSET+1])<<16 |
			uint32(data[TOTAL_USAGE_OFFSET+2])<<8 |
			uint32(data[TOTAL_USAGE_OFFSET+3])
		waterReading := float64(totalValue) / 1000.0
		result["total_flow"] = waterReading
		result["water_reading"] = waterReading
	}

	// 解析电池电压（偏移量26，2字节，大端序，单位0.01V）
	const VOLTAGE_OFFSET = 26
	if len(data) >= VOLTAGE_OFFSET+2 {
		voltage := (uint16(data[VOLTAGE_OFFSET]) << 8) | uint16(data[VOLTAGE_OFFSET+1])
		result["battery_voltage"] = float64(voltage) / 100.0
	}

	// 解析日用量（偏移量47，4字节，大端序，单位升）
	const DAILY_USAGE_OFFSET = 47
	if len(data) >= DAILY_USAGE_OFFSET+4 {
		dailyValue := uint32(data[DAILY_USAGE_OFFSET])<<24 |
			uint32(data[DAILY_USAGE_OFFSET+1])<<16 |
			uint32(data[DAILY_USAGE_OFFSET+2])<<8 |
			uint32(data[DAILY_USAGE_OFFSET+3])
		result["daily_usage"] = float64(dailyValue) / 1000.0
	}

	// 解析月用量（偏移量51，4字节，大端序，单位升）
	const MONTHLY_USAGE_OFFSET = 51
	if len(data) >= MONTHLY_USAGE_OFFSET+4 {
		monthlyValue := uint32(data[MONTHLY_USAGE_OFFSET])<<24 |
			uint32(data[MONTHLY_USAGE_OFFSET+1])<<16 |
			uint32(data[MONTHLY_USAGE_OFFSET+2])<<8 |
			uint32(data[MONTHLY_USAGE_OFFSET+3])
		result["monthly_usage"] = float64(monthlyValue) / 1000.0
	}

	// 设置可读属性
	if valveClosed, ok := result["valve_closed"].(bool); ok {
		if valveClosed {
			result["valve_status"] = "关闭"
		} else {
			result["valve_status"] = "开启"
		}
	}

	if batteryLow, ok := result["battery_low"].(bool); ok {
		if batteryLow {
			result["battery_status"] = "电量低"
		} else {
			result["battery_status"] = "正常"
		}
	}

	if meterError, ok := result["meter_error"].(bool); ok {
		if meterError {
			result["meter_status"] = "故障"
		} else {
			result["meter_status"] = "正常"
		}
	}

	result["signal_strength"] = 99

	return result, nil
}

// parseWaterMeterDataMain 基于main.py方案解析（验证方案）
func parseWaterMeterDataMain(data []byte) (map[string]interface{}, error) {
	if len(data) < 61 {
		return nil, fmt.Errorf("数据长度不足")
	}

	result := make(map[string]interface{})

	// main.py原方案的解析（用于对比验证）
	// 注意：main.py中后付费表的累计用量使用大端序

	// 状态字（位置41-42，大端序）
	if len(data) >= 43 {
		status := (uint16(data[41]) << 8) | uint16(data[42])
		result["status"] = status
		result["valve_closed"] = (status & 0x01) != 0
		result["battery_low"] = (status & 0x02) != 0
		result["meter_error"] = (status & 0x04) != 0
	}

	// 累计用量（位置43-46，大端序）- main.py: parse_postpaid_data
	if len(data) >= 47 {
		totalValue := uint32(data[43])<<24 |
			uint32(data[44])<<16 |
			uint32(data[45])<<8 |
			uint32(data[46])
		result["total_flow"] = float64(totalValue) / 1000.0
		result["water_reading"] = float64(totalValue) / 1000.0
	}

	// 电池电压（位置26-27，大端序）
	if len(data) >= 28 {
		voltage := (uint16(data[26]) << 8) | uint16(data[27])
		result["battery_voltage"] = float64(voltage) / 100.0
	}

	result["signal_strength"] = 99

	return result, nil
}

// compareWaterMeterDifferences 对比两种解析方案的差异并记录日志
func compareWaterMeterDifferences(regexData, mainData map[string]interface{}, deviceAddr string) {
	// 关键字段对比
	keyFields := []string{"total_flow", "water_reading", "battery_voltage", "daily_usage", "monthly_usage"}

	hasDifference := false
	var differences []string

	for _, field := range keyFields {
		regexVal, regexOk := regexData[field]
		mainVal, mainOk := mainData[field]

		// 都存在才对比
		if regexOk && mainOk {
			// 对于float64类型，使用精度对比
			regexFloat, regexIsFloat := regexVal.(float64)
			mainFloat, mainIsFloat := mainVal.(float64)

			if regexIsFloat && mainIsFloat {
				// 允许0.001的误差
				diff := regexFloat - mainFloat
				if diff < 0 {
					diff = -diff
				}
				if diff > 0.001 {
					hasDifference = true
					differences = append(differences, fmt.Sprintf("%s: water_regex=%.3f, main.py=%.3f", field, regexFloat, mainFloat))
				}
			} else if regexVal != mainVal {
				hasDifference = true
				differences = append(differences, fmt.Sprintf("%s: water_regex=%v, main.py=%v", field, regexVal, mainVal))
			}
		} else if regexOk != mainOk {
			// 一个有一个没有
			hasDifference = true
			if regexOk {
				differences = append(differences, fmt.Sprintf("%s: water_regex=%v, main.py=<不存在>", field, regexVal))
			} else {
				differences = append(differences, fmt.Sprintf("%s: water_regex=<不存在>, main.py=%v", field, mainVal))
			}
		}
	}

	if hasDifference {
		zap.S().Warnf("设备[%s] 两种解析方案结果不一致，已采用water_regex方案。差异: %s", deviceAddr, strings.Join(differences, "; "))
	} else {
		zap.S().Debugf("设备[%s] 两种解析方案结果一致", deviceAddr)
	}
}

// TestParse2025F183 测试解析2025F183-37协议报文
func TestParse2025F183() {
	// 测试数据
	data := []byte{
		0x68, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68,
		0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
		0x02, 0x00, 0x00, 0x00, 0x00, 0x16,
	}

	fmt.Println("测试解析2025F183-37协议报文...")
	event, err := Parse2025F183Packet(data)
	if err != nil {
		fmt.Printf("解析失败: %v\n", err)
		return
	}

	fmt.Printf("设备地址: %s\n", event.DeviceAddr)
	if flow, ok := event.EventData["water_reading"].(float64); ok {
		fmt.Printf("水表示数: %.2f 立方米\n", flow)
	}

	fmt.Println("解析测试完成")
	fmt.Println("--------------------------")
}
